using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Camalon.ColorPicker
{
	/// <summary>
	/// Summary description for ColorTraker.
	/// </summary>
	public abstract class ColorTrackerBase : System.Windows.Forms.TrackBar
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		protected ColorTrackerBase()
		{
			// This call is required by the Windows.Forms Form Designer.
			//this.SetStyle( ControlStyles.AllPaintingInWmPaint, true);
			this.SetStyle( ControlStyles.DoubleBuffer,true);
			this.SetStyle( ControlStyles.UserPaint, true );
	
			this.Minimum = 0;
			this.Maximum = 255;

		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}


		private bool _vertical = true;
		protected bool Vertical
		{
			get{ return _vertical;}
			set
			{
				_vertical = value;
				this.Invalidate();
			}
		}


		private int _thumbOffset = 4;
		[DefaultValue ( 4 )]
		public int ThumbOffset
		{
			get{ return _thumbOffset;}
			set{_thumbOffset= value;}
		}


		protected Rectangle DrawingBounds
		{
			get
			{ 
				Rectangle r = this.ClientRectangle;
				r.Inflate(-_thumbOffset, -_thumbOffset);
				return r;

			}
		}

		protected Rectangle SliderBounds
		{
			get
			{ 
				if( _vertical)
				{
					Rectangle bounds = this.DrawingBounds;
					int	y = (int)System.Math.Round((double)this.Value * ((double)bounds.Height/(double)this.Maximum));
					y = bounds.Bottom - _thumbOffset -  y;

					return new Rectangle( _thumbOffset , y , bounds.Width, 2*_thumbOffset);
				}
				else
				{
					Rectangle bounds = this.DrawingBounds;
					int	x = (int)System.Math.Round((double)this.Value * ((double)bounds.Width/(double)this.Maximum));
					x = bounds.Right - _thumbOffset -  x;

					return new Rectangle( x, bounds.Top - _thumbOffset , 2*_thumbOffset, bounds.Height + (2*_thumbOffset));
				}
			}
		}

		
		protected override void OnMouseWheel(MouseEventArgs e)
		{
			base.OnMouseWheel (e);
			ResetColorRenderingValue();
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown (e);
			if( e.Button == MouseButtons.Left) 
				CalculateValue(  new Point( e.X, e.Y) );	
			this.Invalidate();
		}

		protected override void OnMouseMove(MouseEventArgs e)
		{
			base.OnMouseMove (e);
			if( e.Button == MouseButtons.Left) 
				CalculateValue( new Point( e.X, e.Y) );
			this.Invalidate();
		}

		protected override void OnMouseUp(MouseEventArgs e)
		{
			base.OnMouseUp (e);
			Invalidate();
		}

		private void CalculateValue( Point pt )
		{
			
			Rectangle bounds = this.DrawingBounds; 
			
			if( _vertical )
			{
				int pty = pt.Y - _thumbOffset;

				if( pty > bounds.Height)				pty = bounds.Height;
				if( pty < bounds.Top - _thumbOffset)	pty = bounds.Top - _thumbOffset;

				int val = this.Maximum - (int)System.Math.Round((double)pty * (double)this.Maximum / (double)bounds.Height);
				if( val < this.Minimum ) val = this.Minimum; 
				if( val > this.Maximum ) val = this.Maximum;
				base.Value = val;
			}
			else
			{
				int ptx = pt.X - _thumbOffset;

				if( ptx > bounds.Width)					ptx = bounds.Width;
				if( ptx < bounds.Left - _thumbOffset)	ptx = bounds.Left - _thumbOffset;

				int val = this.Maximum - (int)System.Math.Round((double)ptx * (double)this.Maximum / (double)bounds.Width);
				if( val < this.Minimum ) val = this.Minimum; 
				if( val > this.Maximum ) val = this.Maximum;
				base.Value = val;
			}

			ResetColorRenderingValue();
 
		}

		protected abstract void ResetColorRenderingValue();
		

		protected override void OnKeyDown(KeyEventArgs e)
		{

			base.OnKeyDown (e);

			if( e.KeyCode == Keys.Right || 
				e.KeyCode == Keys.Up ||
				e.KeyCode == Keys.Left ||
				e.KeyCode == Keys.Down ||
				e.KeyCode == Keys.PageDown ||
				e.KeyCode == Keys.PageUp ||
				e.KeyCode == Keys.End ||
				e.KeyCode == Keys.Home ) 
			{
				ResetColorRenderingValue();
			}

		}

		protected virtual void DrawSliderThumbs( Graphics graphics )
		{
			Rectangle sb = this.SliderBounds;
			
			if( _vertical )
			{
				PointF pt1 = new PointF( sb.Right, sb.Top + this.ThumbOffset );
				PointF pt2 = new PointF( sb.Right + this.ThumbOffset, sb.Bottom);
				PointF pt3 = new PointF( sb.Right + this.ThumbOffset, sb.Top);
				PointF[] pts = new PointF[]{pt1, pt2, pt3};
				graphics.FillPolygon( Brushes.Black, pts);

				pt1 = new PointF( (sb.Left+1), sb.Top + this.ThumbOffset );
				pt2 = new PointF( (sb.Left+1) - this.ThumbOffset, sb.Bottom);
				pt3 = new PointF( (sb.Left+1) - this.ThumbOffset, sb.Top);
				pts = new PointF[]{pt1, pt2, pt3};
				graphics.FillPolygon( Brushes.Black, pts);
			}
			else
			{
				PointF pt1 = new PointF( sb.Left, sb.Top);
				PointF pt2 = new PointF( sb.Right , sb.Top);
				PointF pt3 = new PointF( sb.Left + this.ThumbOffset, sb.Top + this.ThumbOffset);
				PointF[] pts = new PointF[]{pt1, pt2, pt3};
				graphics.FillPolygon( Brushes.Black, pts);

				pt1 = new PointF( sb.Left, sb.Bottom);
				pt2 = new PointF( sb.Right , sb.Bottom);
				pt3 = new PointF( sb.Left + this.ThumbOffset, sb.Bottom - this.ThumbOffset-1);
				pts = new PointF[]{pt1, pt2, pt3};
				graphics.FillPolygon( Brushes.Black, pts);

			}
		}

		protected virtual  void UpdateSliderColor( Graphics graphics, Rectangle colorRegion)
		{

		}

		private bool _painting;
		protected override void OnPaint(PaintEventArgs e)
		{
			if( _painting ) return;

			try
			{
				Graphics g = e.Graphics;

				GraphicsContainer c = g.BeginContainer();
				Rectangle r = this.DrawingBounds;

				UpdateSliderColor( g, r);
			
				e.Graphics.DrawRectangle( SystemPens.ControlDark,r);

				this.DrawSliderThumbs( e.Graphics);

				#region COMMENTED(Triangle-Bar)

				//				if( ColorRenderingValue.OpacityEnabled )//Triangle
				//				{
				//					PointF pt1 = new PointF( sb.Right, sb.Top + base.ThumbOffset );
				//					PointF pt2 = new PointF( sb.Right + base.ThumbOffset, sb.Bottom);
				//					PointF pt3 = new PointF( sb.Right + base.ThumbOffset, sb.Top);
				//					PointF[] pts = new PointF[]{pt1, pt2, pt3};
				//					e.Graphics.FillPolygon( Brushes.Black, pts);
				//
				//					pt1 = new PointF( (sb.Left+1), sb.Top + base.ThumbOffset );
				//					pt2 = new PointF( (sb.Left+1) - base.ThumbOffset, sb.Bottom);
				//					pt3 = new PointF( (sb.Left+1) - base.ThumbOffset, sb.Top);
				//					pts = new PointF[]{pt1, pt2, pt3};
				//					e.Graphics.FillPolygon( Brushes.Black, pts);
				//
				//				}
				//				else//Draw bar
				//				{
				//					PointF pt1 = new PointF( sb.Right, sb.Top );
				//					PointF pt2 = new PointF( sb.Right, sb.Bottom);
				//					PointF pt3 = new PointF( sb.Right + base.ThumbOffset, sb.Top + base.ThumbOffset);
				//					PointF[] pts = new PointF[]{pt1, pt2, pt3};
				//					e.Graphics.FillPolygon( Brushes.Black, pts);
				//
				//					pt1 = new PointF( sb.Left+1, sb.Top );
				//					pt2 = new PointF( sb.Left+1, sb.Bottom);
				//					pt3 = new PointF( sb.Left+1 - base.ThumbOffset, sb.Top + base.ThumbOffset);
				//					pts = new PointF[]{pt1, pt2, pt3};
				//					e.Graphics.FillPolygon( Brushes.Black, pts);
				//				}
				#endregion COMMENTED(Triangle-Bar)

				g.EndContainer( c );
			}
			finally
			{
				_painting = false;
			}
		}

	}
}
